package com.gxa.controller;

import com.gxa.utils.RedisUtils;
import com.gxa.utils.Result;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class StorageController {

  @Autowired
  private RedisUtils redisUtils;

  @Autowired
  private Redisson redisson;


  /* 分布式锁
    使用redisson的问题？
    由于我们以后的环境都是 主从 或者哨兵 或者集群
    当主节点宕机之后，数据还未同步到从节点，当新的从节点选举为master节点，就没有之前的锁了。。
    怎么解决？
    因为REDIS在主从这些模式下面是AP。
    1、这时我们就需要一个CP模型，所以想到zookeeper
    如果我们使用zookeeper来做分布式锁，就不会出现锁丢失的情况
    2、非要使用redis ，并且也要不丢失锁，官方提供了解决方案 redlock(红锁)
      要求另外再拿三台redis（这三台redis是对等的）
      写锁的时候，要保证 至少半数以上的节点是成功的。
      redlock 本身部署繁琐，官方也说也有一些问题，所以也不推荐
    3、总结：
       如果就是要不丢锁 ，应该选择zk
       如果能接受在极端的情况下有小概率丢锁的事件，可以选择redis来做

   */
    @RequestMapping("/storage/decrease")
    public Result decrease() {
      String lockKey = "goods-100";
      RLock redissonLock = redisson.getLock(lockKey);
      try{
        redissonLock.lock();
        int stock = Integer.parseInt(redisUtils.get("stock"));
        if(stock >0){
          int realStock = stock - 1;
          redisUtils.set("stock",realStock);
          System.out.println("库存扣减成功，剩余库存:" + realStock);
        }else {
          System.out.println("库存扣减失败");
        }
      }finally {
        //保证删的是自己的
        redissonLock.unlock();
      }

      return new Result().ok();
    }
}